﻿using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using Neo4JConnector.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Neo4JConnector
{
    [Icon("pack://application:,,,/Neo4JConnector;component/Resources/Icon.png")]
    [Category("neo4j图数据库")]
    [OrderWeight(20)]
    public class GetNode : BaseNeo4JOp, IServerCommandParamGenerator
    {
        [FormulaProperty]
        [DisplayName("节点的标签")]
        [Description("类似于数据库中的表，用于对节点进行分类。")]
        [OrderWeight(100)]
        [SearchableProperty]
        public object LabelExpr { get; set; }

        [FormulaProperty]
        [DisplayName("节点的ID")]
        [Description("类似于数据库中的行ID，在同一个表内需要保持唯一。")]
        [OrderWeight(101)]
        [SearchableProperty]
        public object IDExpr { get; set; }

        [DisplayName("将节点保存到变量")]
        [OrderWeight(999)]
        [ResultToProperty]
        public string ResultInParamater { get; set; } = "Node";

        public override async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            var label = (await dataContext.EvaluateFormulaAsync(LabelExpr))?.ToString() ?? "";
            var id = (await dataContext.EvaluateFormulaAsync(IDExpr))?.ToString() ?? null;
            
            if (string.IsNullOrEmpty(label) || string.IsNullOrEmpty(id))
            {
                throw new Exception("节点的标签和ID不能为空。");
            }

            if (!Validators.IsValidLabel(label))
                throw new Exception("节点的标签包含非法字符，仅支持字母数字和下划线，且需要以字母开头。");

            var client = await getClient(dataContext);

            var results = await client.GetEntity(label, id);

            if (!string.IsNullOrEmpty(ResultInParamater))
            {
                dataContext.Parameters[ResultInParamater] = results;
            }

            return new ExecuteResult();
        }

        public IEnumerable<GenerateParam> GetGenerateParams()
        {
            yield return new GenerateObjectParam()
            {
                ParamName = this.ResultInParamater,
                Description = "查询节点信息的结果",
                ParamScope = CommandScope.All,
                SubPropertiesDescription = new Dictionary<string, string>() {
                    { "id","节点的唯一标识"},
                    { "labels","节点的标签"},
                    { "properties","节点的属性"}
                }
            };
        }

        public override string ToString()
        {
            return "neo4j：获取节点";
        }
    }
}
